package com.spukmk3me.scene;

import com.spukmk3me.math.Rectangle;

/**
 *  Represent a node in scene.
 *  \details
 *  Default flags: VISIBLE | ENABLE | ANIMATE | USEBLENDING.
 *  Default plane color: 0xFFFFFFFF;
 *  Default additional color: 0;
 */
public abstract class Node
{
    public abstract String getName();
    
    /**
     *  \details Return next sibling. If this node is the last node in it's
     *  sibling list, return the first node. 
     *  @return Next sibling.
     */
    public abstract Node next();
    
    /**
     *  \details Return previous sibling. If this node is the first node in
     *  it's sibling list, return the last node.
     *  @return Previous sibling. 
     */
    public abstract Node prev();
    
    /**
     *  \details Return the direct parent of this node. Unattached node or
     *  root node (in a scene) doesn't have direct parent; returns null in
     *  this case.
     *  @return Direct parent.
     */
    public abstract Node parent();
    
    /**
     *  \details Return the first node in this node's children list. If the node
     *  doesn't have children, returns null;
     *  @return First child node.
     */
    public abstract Node child();
    
    public abstract boolean isFirstSibling();
    public abstract boolean isLastSibling();
    public abstract boolean hasChildren();
    public abstract boolean hasParent();
    
    public abstract void setFlags( int flags );
    public abstract int getFlags();
    
    public abstract void setVisible( boolean visible );
    public abstract boolean getVisible();
    public abstract void setEnable( boolean enable );
    public abstract boolean getEnable();
    public abstract void setAnimating( boolean enable );
    public abstract boolean getAnimating();
    public abstract void setBlendingUsage( boolean useBlending );
    public abstract boolean getBlendingUsage();
    public abstract void setClippingUsage( boolean useClip );
    public abstract boolean getClippingUsage();
    
    public abstract void setPlaneColor( int color );
    public abstract int getPlaneColor();
    public abstract void setAdditionalColor( int color );
    public abstract int getAdditionalColor();

    public abstract void getClip( Rectangle clipData );
    public abstract void setClip( Rectangle clipData );
    public abstract void setClip( int x, int y, int w, int h );
    
    public abstract void setPivot( float x, float y );
    public abstract void setTrans( float x, float y );
    public abstract void setRot( float angle );
    public abstract void setScale( float x, float y );
    
    /*
    public abstract void t( float x, float y, float z );
    public abstract void s( float sx, float sy, float sz );
    public abstract void r( float vx, float vy, float vz, float angle );
    public abstract void c( Matrix4f m );
    */
    public abstract void reset();
   
    /**
     *  Order for rendering, larger value means being rendered later.
     *  \details Top node always have rendering order = 0
     *  If rendering order is set to negative value, the actual rendering order
     * number will be <direct parent's order> + 1.
     *  If two nodes have the same order number, the actual order will be
     * decided by scene.
     */
    public abstract void setRenderOrder( int order );
    public abstract int getRenderOrder();
    
    public final Entity getEntity()
    {
        return m_entity;
    }
    
    public final void setEntity( Entity entity )
    {
        if ( m_entity != null )
            m_entity.decResourceCounter();

        m_entity = entity;
        
        if ( m_entity != null )
            m_entity.incResourceCounter();
    }
    
    /**
     *  Make the animator reference this node.
     *  \details Implements of Node class must call it in addAnimator(). 
     */
    protected final void _attachAnimator( Animator animator )
    {
    	animator.setNode( this );
    }
    
    /**
     *  Make the animator reference to null node.
     *  \details Implements of Node class must call it in removeAnimator().
     */
    protected final void _detachAnimator( Animator animator )
    {
    	animator.setNode( null );
    }
    
    public abstract void addAnimator( Animator animator );
    public abstract void removeAnimator( Animator animator );
    public abstract void removeAllAnimators();
    
    public static final int VISIBLE     = 0x00000001;
    public static final int ENABLE      = 0x00000002;
    public static final int USECLIPPING = 0x00000004;
    public static final int ANIMATE     = 0x00000008;
    public static final int USEBLENDING = 0x00000010;
    
    private Entity              	m_entity;
}